package core.api.offer;

import jade.util.Logger;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;

import core.datamodel.AccountData;
import core.datamodel.Constants;
import core.datamodel.Element;
import core.datamodel.ElementValue;
import core.datamodel.Resource;
import core.datamodel.ResourceCounter;

public class OfferDataReplication {
	private OfferHelper offerModel = null;
	private Logger log = Logger.getJADELogger(this.getClass().getName());
	private boolean flat = false;

	private ArrayList<ElementValue> accountValues = new ArrayList<ElementValue> ();
	private ArrayList<ResourceCounter> accountCounters = new ArrayList<ResourceCounter> ();
	private AccountData account = new AccountData();

	public OfferDataReplication(boolean flat){
		this.flat = flat;
	}

	public AccountData calculate(Resource resource, Date startTime,	long interval) {
		log.info("Richiesto il calcolo per VirtualMachine offerta a consumo per il timestamp " + startTime);
		offerModel = new OfferHelper( resource, startTime,interval);
		if (flat)
			offerDataReplicationFlat( resource, startTime, interval);

		account.setCounters(accountCounters);
		account.setElementValues(accountValues);

		return account;

	}

	private void offerDataReplicationFlat (Resource resource, Date startTime,	long interval ){
		log.info("Offerta Flat con template");

		Hashtable<String, Float> templateCosts = new Hashtable<String, Float> ();
		templateCosts.put("Linux Silver", (float) 3000);
		templateCosts.put("Linux Silver Plus", (float) 6000);
		templateCosts.put("Linux Gold", (float) 9000);
		templateCosts.put("Linux Gold Plus", (float) 12000);

		// storage
		Hashtable<String, Float> templateStorageSizes = new Hashtable<String, Float> ();
		templateStorageSizes.put("Linux Silver", (float) 500);
		templateStorageSizes.put("Linux Silver Plus", (float) 750);
		templateStorageSizes.put("Linux Gold", (float) 1000);
		templateStorageSizes.put("Linux Gold Plus", (float) 2000);

		float monthlyStorageAddedCost = (float) 80 / (float) 500;
		float storageTemplateSize = 0;

		// get  template name
		String templateName = null;
		for (Element ele : resource.getElements()){
			if (ele.getName().equals(Constants.DATA_REPLICATION_ELEMENT_TEMPLATE)){
				templateName = ele.getValue();
				break;
			}
		}

		Float templateCost = templateCosts.get(templateName);
		System.out.println(" templateName = " + templateName );
		if (templateCost != null){
			
			float monthlyCost = templateCost.floatValue();
			storageTemplateSize = templateStorageSizes.get(templateName).floatValue();

			System.out.println("Trovato template " + templateName + " costo "+monthlyCost );

			ResourceCounter dayCounter = offerModel.getDayCounter("CHECK_DATE_DBREP_FLAT", flat);

			if ( dayCounter.isNewCounter() | 
					(( (long)((startTime.getTime() / Constants.MILLIS_DAY) )* Constants.MILLIS_DAY) != 
						dayCounter.getLastUpdate().getTime())  ){
				// new day generate account data

				for (Element ele : resource.getElements()){
					System.out.println(ele.getName());

					if (ele.getName().equals(Constants.DATA_REPLICATION_ELEMENT_TEMPLATE) ){
						accountValues.add( offerModel.getElementValue(ele, dayCounter, monthlyCost, true));

					} else 	if (ele.getName().equals(Constants.DATA_REPLICATION_ELEMENT_STORAGE) ){
						
						// normalizzo per pagare solo lo storage aggiuntivo
						float cost = 0;
						int totStorge = new Integer(ele.getValue()).intValue();
						cost = ((totStorge-storageTemplateSize) * monthlyStorageAddedCost )  / totStorge;

						accountValues.add( offerModel.getElementValue(ele, dayCounter, cost, true));
					}

				} // end for

				dayCounter.setUpdateCounter(true);
				// set normaliza date
				long time = (long) ((long) ( startTime.getTime()/ Constants.MILLIS_DAY)* Constants.MILLIS_DAY );
				dayCounter.setLastUpdate( new Date(time)  );
				accountCounters.add(dayCounter);

			} else {
				log.info("No new day and no account date must be generated for resource name="+resource.getResourceName());
			}

		} else {
			log.info("Error no found template name .... calculate offer with no template");
		}

	}


}